//
//  ARCViewController.m
//  ExerciseOC
//
//  Created by 王子曦 on 2025/4/14.
//

#import "ARCViewController.h"
#import "Person.h"

@interface ARCViewController ()
@property (nonatomic, strong) UITextView *textView;
@property (nonatomic, strong) Person *person;
@end

@implementation ARCViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.title = @"ARC内存管理";
    
    // 创建文本视图
    self.textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 120, self.view.bounds.size.width, self.view.bounds.size.height - 170)];
    self.textView.editable = NO;
    self.textView.font = [UIFont systemFontOfSize:16];
    [self.view addSubview:self.textView];
    
    // 添加两个按钮
    UIButton *withoutPoolButton = [UIButton buttonWithType:UIButtonTypeSystem];
    withoutPoolButton.frame = CGRectMake(20, 370, 160, 40);
    [withoutPoolButton setTitle:@"无自动释放池" forState:UIControlStateNormal];
    [withoutPoolButton addTarget:self action:@selector(processLargeDataSetWithoutPool) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:withoutPoolButton];
    
    UIButton *withPoolButton = [UIButton buttonWithType:UIButtonTypeSystem];
    withPoolButton.frame = CGRectMake(200, 370, 160, 40);
    [withPoolButton setTitle:@"使用自动释放池" forState:UIControlStateNormal];
    [withPoolButton addTarget:self action:@selector(processLargeDataSetWithPool) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:withPoolButton];
    
    // 设置内容
    NSMutableString *content = [NSMutableString string];
    [content appendString:@"ARC (Automatic Reference Counting) 是iOS中的自动引用计数机制\n\n"];
    [content appendString:@"1. ARC的工作原理：\n"];
    [content appendString:@"   - 编译器会自动插入retain/release/autorelease\n"];
    [content appendString:@"   - 开发者不需要手动管理内存\n"];
    [content appendString:@"   - 编译器会在适当的位置插入内存管理代码\n\n"];
    
    [content appendString:@"2. 属性修饰符：\n"];
    [content appendString:@"   - strong：强引用，引用计数+1\n"];
    [content appendString:@"   - weak：弱引用，不增加引用计数\n"];
    [content appendString:@"   - copy：拷贝对象\n"];
    [content appendString:@"   - assign：用于基本数据类型\n\n"];
    
    [content appendString:@"3. 代码示例：\n"];
    [content appendString:@"   Person *person = [[Person alloc] init];  // 引用计数为1\n"];
    [content appendString:@"   person.name = @\"张三\";  // 属性修饰符为copy\n"];
    [content appendString:@"   person = nil;  // 自动release，引用计数归零\n\n"];
    
    [content appendString:@"4. ARC的优点：\n"];
    [content appendString:@"   - 避免手动管理内存的错误\n"];
    [content appendString:@"   - 减少内存泄漏的可能性\n"];
    [content appendString:@"   - 提高开发效率\n\n"];
    
    [content appendString:@"5. 注意事项：\n"];
    [content appendString:@"   - 循环引用问题需要特别注意\n"];
    [content appendString:@"   - 使用weak或unowned避免循环引用\n"];
    [content appendString:@"   - Core Foundation对象需要手动管理\n\n"];
    
    [content appendString:@"6. ARC自动插入retain/release验证：\n"];
    [content appendString:@"   - 创建对象时自动retain\n"];
    [content appendString:@"   - 赋值给strong属性时自动retain\n"];
    [content appendString:@"   - 离开作用域时自动release\n"];
    [content appendString:@"   - 方法返回对象时自动autorelease\n\n"];
    
    // 验证ARC自动插入retain/release的代码示例
    [self demonstrateARCRetainRelease];
    
    self.textView.text = content;

    [self demonstrateAutoreleasePool];
}

- (void)demonstrateARCRetainRelease {
    // 1. 创建对象时自动插入retain
    // 编译器会在[[Person alloc] init]后自动插入retain
    Person *person1 = [[Person alloc] init];
    person1.name = @"person1";
    // 2. 赋值给strong属性时自动retain
    // 编译器会在self.person = person1时自动插入retain
//    self.person = person1;
    
    // 3. 离开作用域时自动release
    // 编译器会在person1离开作用域时自动插入release
    
    // 4. 方法返回对象时自动autorelease
    // 编译器会在返回person1时自动插入autorelease
    Person *person2 = [self createPerson];
    person2.name = @"person2";
    // 5. 自动释放池示例
    @autoreleasepool {
        Person *tempPerson = [self createPerson]; // 对象会被放入当前池
        tempPerson.name = @"tempPerson";
        NSLog(@"临时对象创建完成");
    } // 池在此销毁，tempPerson会被释放
    NSLog(@"自动释放池已销毁");
}

- (Person *)createPerson {
    Person *person = [[Person alloc] init];
    // 编译器会在return前自动插入autorelease
    return person;
}

- (void)demonstrateAutoreleasePool {
    // 1. 没有使用自动释放池的情况（内存会持续增长）
//    [self processLargeDataSetWithoutPool];
    
    // 2. 使用自动释放池优化内存
     [self processLargeDataSetWithPool];
}

- (void)processLargeDataSetWithoutPool {
    NSMutableArray *results = [NSMutableArray array];
    
    // 模拟处理大量数据（内存会持续增长）
    for (int i = 0; i < 200000; i++) {
        // 每次循环都创建临时对象
        NSString *tempString = [NSString stringWithFormat:@"临时对象%d", i];
        NSDictionary *tempDict = @{@"key": tempString};
        
        [results addObject:tempDict];
    }
    
    NSLog(@"处理完成，结果数量: %lu", (unsigned long)results.count);
}

- (void)processLargeDataSetWithPool {
    NSMutableArray *results = [NSMutableArray array];
    
    // 使用自动释放池优化内存
    for (int i = 0; i < 200000; i++) {
        @autoreleasepool {
            // 创建临时对象
            NSString *tempString = [NSString stringWithFormat:@"临时对象%d", i];
            NSDictionary *tempDict = @{@"key": tempString};
            
            [results addObject:tempDict];
            
            // 每100次循环打印内存状态
            if (i % 100 == 0) {
                NSLog(@"处理进度: %d", i);
            }
        } // 临时对象在这里被释放
    }
    
    NSLog(@"优化处理完成，结果数量: %lu", (unsigned long)results.count);
}
@end
